using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Drawing.Imaging;

namespace DareMusicFixer
{
    public partial class Form1 : Form
    {
        bool mIsStopped = true;

        string mTitle = "Dare Music Fixer";

        string mLastAlbum = null;
        string mLastAlbumChange = null;

        string mLastArtist = null;
        string mLastArtistChange = null;
                                
        public Form1()
        {
            InitializeComponent();

            new Log(logBox);

            Log.WriteLine("Dare Music Fixer 1.1");            
            Log.WriteLine("Written By Peter Kuhn");
            Log.WriteLine("September 04 2008");
            Log.WriteLine(" ");
            Log.WriteLine("Select your my_music folder");            
        }

        private void button1_Click(object sender, EventArgs e)
        {            
            MakeButtonStop();

            DialogResult dr = folderBrowserDialog1.ShowDialog();

            if (dr == DialogResult.OK)
            {
                string path = folderBrowserDialog1.SelectedPath;

                Thread t = new Thread(new ParameterizedThreadStart(Go));
                t.SetApartmentState(ApartmentState.STA);
                t.Start(path);
            }
            else
            {
                MakeButtonGo();
            }
        }

        void button1_Stop(object sender, EventArgs e)
        {
            mIsStopped = true;
        }

        void MakeButtonStop()
        {
            mIsStopped = false;
            button1.Click -= new EventHandler(button1_Click);
            button1.Click += new EventHandler(button1_Stop);
            button1.Text = "Stop";
        }

        delegate void MakeButtonGoDelegate();
        void MakeButtonGo()
        {
            if (button1.InvokeRequired)
            {
                MakeButtonGoDelegate d = new MakeButtonGoDelegate(MakeButtonGo);
                button1.Invoke(d);
            }
            else
            {
                mIsStopped = true;
                button1.Click -= new EventHandler(button1_Stop);
                button1.Click += new EventHandler(button1_Click);
                button1.Text = "Go";
            }
        }

        delegate void SetPercentDelegate(int percent);
        void SetPercent(int percent)
        {
            if (this.InvokeRequired)
            {
                SetPercentDelegate d = new SetPercentDelegate(SetPercent);
                this.Invoke(d, new object[] { percent });                
            }
            else
            {
                progressBar1.Value = percent;
                if (percent > 0)
                {
                    this.Text = percent + "% " + mTitle;
                }
                else
                {
                    this.Text = mTitle;
                }
            }
        }

        void Go(object data)
        {
            Log.Clear();

            string path = (string)data;
            Log.Write("Folder Selected: " + path);

            int numFails = 0;
                        
            if (Directory.Exists(path))
            {
                Log.WriteLine(" Exists");

                Log.WriteLine("Files: ");

                int counter = 1;
                int numFiles = Directory.GetFiles(path, "*.mp3").Length;

                foreach (String file in Directory.GetFiles(path, "*.mp3"))
                {
                    Log.WriteBreak();
                    
                    SetPercent((int)(counter * 100.0f / numFiles));

                    Log.WriteLine("File " + counter + "/" + numFiles);

                    DareMp3Tag dtag = new DareMp3Tag(file);
                    if (dtag.TagLibFile != null)
                    {

                        int numPics = dtag.TagLibFile.Tag.Pictures.Length;
                        Log.WriteLine("num pictures: " + numPics);

                        if (numPics > 0 && !replaceAllArt.Checked)
                        {
                            if (!dtag.IsValid)
                            {
                                TagDisplay td = new TagDisplay(dtag);
                                td.ShowDialog();
                            }
                        }
                        else
                        {
                            Log.WriteLine("Grabbing image from amazon ...");
                            AlbumArtGrabber grabber = new AlbumArtGrabber();

                            if (dtag.Album == mLastAlbum)
                            {
                                dtag.Album = mLastAlbumChange;
                            }
                            else
                            {
                                mLastAlbum = dtag.Album;
                            }

                            if (dtag.Artist == mLastArtist)
                            {
                                dtag.Artist = mLastArtistChange;
                            }
                            else
                            {
                                mLastArtist = dtag.Artist;
                            }

                            if (!grabber.GrabCover(dtag.Artist, dtag.Album) || dtag.Title == "" || dtag.Track == 0 || dtag.Artist == "" || dtag.Album == "")
                            {
                                if (dtag.Title == "")
                                    Log.WriteLine("Title is blank!");

                                if (dtag.Track == 0)
                                    Log.WriteLine("Track is 0!");

                                TagDisplay td = new TagDisplay(dtag);
                                td.ShowDialog();
                            }
                            else
                            {
                                if (grabber.Image != null)
                                {
                                    dtag.Image = grabber.Image;
                                }
                            }

                            mLastAlbumChange = dtag.Album;
                            mLastArtistChange = dtag.Artist;
                        }

                        if (dtag.Image != null)
                        {
                            // Determine if the image is too large for the dare
                            float imgSize = ImageHelpers.ImageSizeKB(dtag.Image.Length, 1);
                            Log.WriteLine("pic size: " + imgSize + " kb");

                            if (imgSize > 50.0f)
                            {
                                Log.WriteLine("Size above 50 kb, scaling to 200x200 ...");

                                dtag.Image = ImageHelpers.Scale(ImageHelpers.ByteArrayToImage(dtag.Image), 200, 200);

                                Log.WriteLine("new size: " + ImageHelpers.ImageSizeKB(dtag.Image.Length, 1));
                            }

                            pictureBox1.Image = ImageHelpers.ByteArrayToImage(dtag.Image);
                        }

                        // figure out if we need to rename the title
                        string type = @"^[a-z]\-(.*)";

                        if (dtag.Title != null)
                        {
                            Match m = Regex.Match(dtag.Title, type);

                            if (!m.Success && dtag.Track != 0 && renameTitles.Checked)
                            {
                                if (dtag.Track <= 26)
                                {
                                    Log.WriteLine("Renaming title to " + (char)('a' - 1 + dtag.Track) + "-" + dtag.Title);
                                    dtag.Title = (char)('a' - 1 + dtag.Track) + "-" + dtag.Title;
                                }
                            }
                            else if (m.Success && !renameTitles.Checked)
                            {
                                Log.WriteLine("Renaming title to original.");
                                dtag.Title = m.Groups[1].Value;
                            }
                        }

                        dtag.Save();
                    }
                    else
                    {
                        Log.WriteLine("Problem with mp3.");
                    }
                    
                    Log.WriteBreak();

                    if (mIsStopped) break;

                    ++counter;
                    Thread.Sleep(1);                    
                }

                Log.WriteLine("Process Complete.");

                //Log.WriteLine("Process Complete with " + (numFails == 0 ? "no" : numFails) + " failure(s).");
            }

            MakeButtonGo();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            mIsStopped = true;
            Close();
        }

        private void openSingleMP3ToolStripMenuItem_Click(object sender, EventArgs e)
        {            
            DialogResult dr = openFileDialog1.ShowDialog();

            if (dr == DialogResult.OK)
            {
                int numFiles = openFileDialog1.FileNames.Length;
                int count = 0;

                foreach (string file in openFileDialog1.FileNames)
                {
                    DareMp3Tag dtag = new DareMp3Tag(file);
                                        
                    TagDisplay td = new TagDisplay(dtag);
                    td.SetNumCompleted(count + 1, numFiles);
                    DialogResult tddr = td.ShowDialog();

                    if (tddr == DialogResult.OK)
                    {
                        if (dtag.Image != null && dtag.Image.Length != 0)
                        {
                            Log.WriteLine("Image Size: " + ImageHelpers.ImageSizeKB(dtag.Image.Length, 2) + " KB");

                            if (ImageHelpers.ImageSizeKB(dtag.Image.Length, 2) > 50.0f)
                            {
                                dtag.Image = ImageHelpers.Scale(ImageHelpers.ByteArrayToImage(dtag.Image), 200, 200);

                                Log.WriteLine("Resized to: " + ImageHelpers.ImageSizeKB(dtag.Image.Length, 2) + " KB");
                            }
                        }

                        dtag.Save();
                    }

                    ++count;
                }
            }            
        }
    }
}